import sqlalchemy as sa
from formencode import validators as fe

from clutch import database as db
from clutch.topes.base import *

__all__ = [ 'TextField', 'SimpleForm', 'FieldSet',
            'RegexField', 'SSN', 'Date', 'Time', 'Currency',
            'Number', 'NumberSpinner', 'NumberSlider',
            'LongText', 'ResizingLongText', 'RichText',
            'ContentPane', 'TabContainer']

############################################################
## Custom Validators
############################################################
class RegexValidator(fe.Regex):

    def message(self, msg, state):
        if msg == 'invalid':
            return self.invalid_message
        else:
            return fe.Regex.message(self, msg)

class RichValidator(fe.UnicodeString):

    def _to_python(self, value, state):
        value = value.replace('\xa0', '&nbsp;')
        return fe.UnicodeString._to_python(self, value, state)

############################################################
## Form Fields
############################################################

class TextField(Tope):
    engine='genshi'
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.ValidationTextBox"
    maxLength="$tope.max_length"
    promptMessage="$tope.help"
    />'''
    min_length=None
    max_length=None
    help=None
    _dojo_requires = ['dijit.form.ValidationTextBox']
    wrapper_args = dict(help=None) # Handled by JS
    
    def __init__(self, name, **kw):
        Tope.__init__(self, name, **kw)
        if self.validator is None:
            self.validator = fe.UnicodeString(min=self.min_length, max=self.max_length)

    def sa_columns(self):
        return [ sa.Column(self.name, sa.Unicode(length=self.max_length), default=self.default) ]

class RegexField(TextField):
    engine='genshi'
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.ValidationTextBox"
    maxLength="$tope.max_length"
    regExp="$tope.jsRegExp"
    promptMessage="$tope.help"
    invalidMessage="$tope.invalid_message"
    />'''
    regex=None
    jsRegExp=None
    invalid_message = 'The input is invalid'
    _dojo_requires = ['dijit.form.ValidationTextBox']
    wrapper_args = dict(help=None, invalid_message=None) # Handled by JS
    
    def __init__(self, name, **kw):
        TextField.__init__(self, name, **kw)
        if self.jsRegExp is None:
            self.jsRegExp = self.regex
        self.validator = RegexValidator(self.regex)
        self.validator.invalid_message = self.invalid_message

class SSN(RegexField):
    regex='\d{3}-\d{2}-\d{4}'
    invalid_message = 'Please enter in the format ###-##-####'
    help='Social Security Number (###-##-####)'

class Date(TextField):
    engine='genshi'
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.DateTextBox"
    promptMessage="$tope.help"
    />'''
    help=None
    _dojo_requires = ['dijit.form.DateTextBox']
    wrapper_args = dict(help=None)
    
class Time(TextField):
    engine='genshi'
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.TimeTextBox"
    promptMessage="$tope.help"
    />'''
    help=None
    _dojo_requires = ['dijit.form.TimeTextBox']
    wrapper_args = dict(help=None)

class Currency(TextField):
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.CurrencyTextBox"
    promptMessage="$tope.help"
    />'''
    _dojo_requires = [ 'dijit.form.CurrencyTextBox' ]

class Number(TextField):
    template='''<input xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    type="text" value="$value"
    dojoType="dijit.form.NumberTextBox"
    promptMessage="$tope.help"
    />'''
    _dojo_requires = [ 'dijit.form.NumberTextBox' ]
    
class NumberSpinner(Tope): pass
class NumberSlider(Tope): pass
    

class LongText(TextField):
    template='''<textarea xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    dojoType="dijit.form.SimpleTextarea"
    rows="$tope.rows" cols="$tope.cols"
    >$value</textarea>'''
    rows=4
    cols=None
    validator=fe.UnicodeString()
    _dojo_requires = [ 'dijit.form.SimpleTextarea' ]
    
class ResizingLongText(LongText):
    template='''<textarea xmlns:py="http://genshi.edgewall.org/"
    name="$name" id="$name" py:attrs="attrs"
    dojoType="dijit.form.Textarea"
    >$value</textarea>'''
    _dojo_requires = [ 'dijit.form.Textarea' ]

class RichText(LongText):
    template='rich_text.html'
    _dojo_onload=['''
    var editor = dijit.byId('${name}_editor');
    console.log('Got editor', editor);
    dojo.connect(editor, 'onNormalizedDisplayChanged',
        function() {
            console.log('Display changed');
            dojo.byId('$name').value = dijit.byId('${name}_editor').getValue();
        });    
    ''']
    _dojo_requires = [ 'dijit.Editor' ]
    validator = RichValidator()

    def display(self, value=None, **kw):
        for part in LongText.display(self, value, **kw):
            print part
            yield part
        




############################################################
## Compound Topes
############################################################
class SimpleForm(CompoundTope):
    engine='genshi'
    template='simple_form.html'
    method = 'POST'
    action = '.'
    submit_text = 'Submit'

    def name_for(self, field, name=None):
        return field.name
        
class FieldSet(CompoundTope):
    engine='genshi'
    template='fieldset.html'
    show_legend = True
    layout_only = True

class ContentPane(FieldSet):
    template='contentpane.html'
    show_legend = True
    layout_only = True
    _dojo_requires=['dijit.layout.ContentPane']

class TabContainer(CompoundTope):
    engine='genshi'
    template='tabcontainer.html'
    attrs=dict(style='width:100%; height:20em')
    layout_only = True
    _dojo_requires=['dijit.layout.TabContainer']
    
class AccordionContainer(CompoundTope):
    engine='genshi'
    template='accordioncontainer.html'
    attrs=dict(style='width:100%; height:20em')
    layout_only = True
    _dojo_requires=['dijit.layout.AccordionContainer']
    
